#include <iostream>
#include <sqlite3.h>
#include "sqliteDataBase.h"
#include <iomanip> // setw(20)设置位宽

using namespace std;

#define BUFFER_SIZE 128

// 插入数据的函数
void demoexec(sqlite3 *musicDb)
{
#if 0
    // 将数据插入到数据库
    const char *sql = "INSERT INTO userInfo (username, passwd) VALUES ('zhaoliu', '123');"; // sqlite语句

    // 执行sql语句
    ret = sqlite3_exec(musicDb, sql, NULL, NULL, NULL);
    if (ret != SQLITE_OK)
    {
        cout << "sqlite exec error." << endl;
        exit(-1);
    }
#endif
    // 手动插入数据
    string username, passwd;
    cout << "请输入用户名：" << endl;
    cin >> username;
    cout << "请输入密码：" << endl;
    cin >> passwd;

#if 0
    string sql = "INSERT INTO userInfo (username, passwd) VALUES ('" + username + "', '" + passwd + "');";

    int ret = sqlite3_exec(musicDb, sql.c_str(), NULL, NULL, NULL);
    if (ret != SQLITE_OK)
    {
        cout << "sqlite exec error." << endl;
        exit(-1);
    }
#else
    // 格式化字符串
    const char *sql = "INSERT INTO userInfo (username, passwd) VALUES ('%s', '%s');"; // sqlite语句
    char requestSql[BUFFER_SIZE] = {0};
    sprintf(requestSql, sql, username.c_str(), passwd.c_str());
    // sprintf 函数将格式化的字符串输出到 requestSql 数组中。它的参数依次为：
    // 第一个参数是目标字符数组 requestSql，用于存放格式化后的字符串
    // 第二个参数是格式化字符串 sql，里面包含占位符 %s
    // 后面的参数 username.c_str() 和 passwd.c_str() 是需要插入到格式化字符串中的实际值
    // c_str() 是 std::string 类的成员函数，它返回一个指向字符串内容的常量字符指针

    // 执行sql语句
    int ret = sqlite3_exec(musicDb, requestSql, NULL, NULL, NULL);
    if (ret != SQLITE_OK)
    {
        cout << "sqlite exec error." << endl;
        exit(-1);
    }
#endif
}

// 查询数据的函数
void demoSelect(sqlite3 *musicDb)
{
    // 查询数据
    const char *sql = "select * from userInfo;";
    char **result = NULL;
    int rows = 0; // 行
    int columns = 0; // 列

    // 用于执行 SQL 查询并将查询结果以二维数组的形式存储在内存中
    // 它适合处理较小的查询结果，因为它会将所有数据加载到内存中
    // 但对于大型数据集，建议使用更灵活的 sqlite3_prepare_v2 等接口
    int ret = sqlite3_get_table(musicDb, sql, &result, &rows, &columns, NULL);
    if (ret != SQLITE_OK)
    {
        cout << "sqlite3 get table error." << endl;
        exit(-1);
    }
    cout << "rows:" << rows << endl;
    cout << "columns:" << columns << endl;

    cout << "result[0]:" << result[0] << endl;
    cout << "result[1]:" << result[1] << endl;
    cout << "result[2]:" << result[2] << endl;
    cout << "result[3]:" << result[3] << endl;

    for (int row = 0; row < rows; row++)
    {
        for (int col = 0; col < columns; col++)
        {
            cout << result[row * columns + col] << "\t"; // 打印地址而非字符
        }
        cout << endl;
    }
}

int main()
{
#if 0
    const char *dbName = "./music.db";

    // 数据库句柄
    sqlite3 *musicDb = NULL; // 指向 SQLite 数据库的指针

    // 打开数据库
    int ret = sqlite3_open(dbName, &musicDb);
    if (ret != SQLITE_OK)
    {
        cout << "sqlite3 open error" << endl;
        exit(-1);
    }

    // 插入数据
    // demoexec(musicDb);

    // 查询数据
    demoSelect(musicDb);

    // 关闭数据库
    sqlite3_close(musicDb);
#endif

#if 1
    SqliteDataBase sqliteDB;

    // 连接数据库
    const char *dbName = "./music.db";
    sqliteDB.connectDB(dbName);

    // const char *sql = "INSERT INTO userInfo (username, passwd) VALUES ('mr_lv', '1030');"; // sqlite语句
    // sqliteDB.executeSql(sql);

    const char *sql = "select * from userInfo;";
    QueryResult res = sqliteDB.querySql(sql);

    for (int idx = 0; idx < res.columnName.size(); idx++)
    {
        cout << res.columnName[idx] << "\t";
    }
    cout << endl;

    int rows = res.rows.size();
    for (int idx = 0; idx < rows; idx++)
    {
        // 每一行的数据
        vector<string> rowData = res.rows[idx];

        for (int jdx = 0; jdx < rowData.size(); jdx++)
        {
            cout << rowData[jdx] << "\t";
        }
        cout << endl;
    }

    sqliteDB.close();
#endif

    return 0;
}